package rosetti.AR.dossier.premier;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.openintents.intents.WikitudeARIntent;
import org.openintents.intents.WikitudePOI;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

/**AR_premier est l'activité principale de l'application "Table d'orientation".
 * Elle gère l'interface utilisateur principale avec les différents boutons d'options. 
 * C'est ici aussi que l'on lance les différents Threads de calcul. * 
 * 
 * @author Emmanuel
 * @version 1.1
 * 
 *
 */
public class AR_premier extends Activity {

	/**Fonction utilisée pour obtenir l'altitude d'un point via
	 * le webservice de Geonames Elevation.
	 * Ce webservice ne permet que 2000 requêtes par heure en utilisation gratuite avec un 
	 * nom d'utilisateur.
	 * @param longitude (double)
	 * @param latitude (double)
	 * @return altitude (double)
	 */
	static double getElevationfromGeonames(double longitude,
			double latitude) {
		Random rand= new Random();
		double result = Double.NaN;
		HttpGet httpGet;
		HttpClient httpClient = new DefaultHttpClient();
		HttpContext localContext = new BasicHttpContext();
		String url = Messages.getString("AR_premier.14") + Messages.getString("AR_premier.15") //$NON-NLS-1$ //$NON-NLS-2$
				+ String.valueOf(latitude)
				+ Messages.getString("AR_premier.16") //$NON-NLS-1$
				+ String.valueOf(longitude)
				+ Messages.getString("AR_premier.17"); //$NON-NLS-1$
		String url2 = Messages.getString("AR_premier.14") + Messages.getString("AR_premier.15") //$NON-NLS-1$ //$NON-NLS-2$
				+ String.valueOf(latitude)
				+ Messages.getString("AR_premier.16") //$NON-NLS-1$
				+ String.valueOf(longitude)
				+ Messages.getString("AR_premier.17bis"); //$NON-NLS-1$
		if(rand.nextBoolean()){
			httpGet = new HttpGet(url);
		}else{
			httpGet = new HttpGet(url2);
		}
		try {
			HttpResponse response = httpClient.execute(httpGet, localContext);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				InputStream instream = entity.getContent();
				int r = -1;
				StringBuffer respStr = new StringBuffer();
				while ((r = instream.read()) != -1)
					respStr.append((char) r);
				String tagOpen = Messages.getString("AR_premier.18"); //$NON-NLS-1$
				String tagClose = Messages.getString("AR_premier.19"); //$NON-NLS-1$
				if (respStr.indexOf(tagOpen) != -1) {
					int start = respStr.indexOf(tagOpen) + tagOpen.length();
					int end = respStr.indexOf(tagClose);
					String value = respStr.substring(start, end);
					result = (Double.parseDouble(value));
				}
				instream.close();
			}
		} catch (ClientProtocolException e) {
		} catch (IOException e) {
		}
		
		return result;
	}
	private static String Tag = Messages.getString("AR_premier.0"); //$NON-NLS-1$
	static int range_tot;
	private LocationManager locationManager;
	private LocationListener listenerGPS;
	private String GpsProvider;
	private String networkProvider;
	static Location ici;
	private Collection<WikitudePOI> poisvisibles2, visibles_temp;
	private ArrayList<WikitudePOI> list_pois_base_wiki;
	private Button arwikitude, voirPOIs, ajoutPOIs, artout, mappoi;
	private static XMLParser xmlparser;
	private static String xml;
	private static Document doc;
	private Thread wiki_visible, test, thread_visible,reload,reload_visible;
	static ArrayList<WikitudePOI> listtoutpois = new ArrayList<WikitudePOI>();
	public static final String PREFS_NAME = "MyPrefsFile";
	public static String MD5 = "77:3E:DA:28:24:A5:07:E2:F7:58:9D:73:59:FB:55:4C";
	private static final int TWO_MINUTES = 1000 * 60 * 2;
    private boolean mToggleIndeterminate = true;
    static boolean chargé = false;
	/**Fonction utilisée pour récupérer des POIs via un autre webservice de Geonames.
	 * On y récupére des points d'intêrets Wikipedia dans un rayon défini par range autour de la position loc.
	 * @param loc Position autour de laquelle on cherche les POIs
	 * @param range Rayon de recherche des POIs en km
	 * @param ctxt Contexte de l'application
	 * @return Liste de POIs tirés de la BD de Wiki
	 */
	static ArrayList<WikitudePOI> getPOISWiki2(final Location loc, final int range,
			Context ctxt) {
		
		
		xmlparser = new XMLParser();
		xml = xmlparser.getXmlFromUrl(prepareURL(loc, range));
		doc = xmlparser.getDomElement(xml);
		ArrayList<WikitudePOI> listdepois = new ArrayList<WikitudePOI>();

		
		NodeList nl = doc.getElementsByTagName(Messages
				.getString("AR_premier.25")); //$NON-NLS-1$

		// looping through all item nodes <item>
		for (int i = 0; i < nl.getLength(); i++) {
			Element e = (Element) nl.item(i);

			String name = xmlparser.getValue(e,
					Messages.getString("AR_premier.26")); //$NON-NLS-1$
			String description = xmlparser.getValue(e,
					Messages.getString("AR_premier.27")); //$NON-NLS-1$
			double lat = Double.parseDouble(xmlparser.getValue(e,
					Messages.getString("AR_premier.28"))); //$NON-NLS-1$
			double lng = Double.parseDouble(xmlparser.getValue(e,
					Messages.getString("AR_premier.29"))); //$NON-NLS-1$
			String url = xmlparser.getValue(e, "wikipediaUrl");
			WikitudePOI poi = new WikitudePOI(lat, lng,
					getElevationfromGeonames(lng, lat), name, description);
			poi.setIconresource(ctxt.getResources().getResourceName(
					R.drawable.ic_wikipedia));
			Log.i("AR", url);
			poi.setLink(url);
			
			listdepois.add(poi);
			poi = null;
		}

		
		chargé=true;
		return listdepois;
	}
	/**Prépare l'URL servant à la requète au webservice Geonames wikipedia
	 * @param location Position autour de laquelle on cherche les POIs
	 * @param range Rayon de recherche des POIs
	 * @return url 
	 */
	private static String prepareURL(Location location, int range) {
		String url;
		String url1 = Messages.getString("AR_premier.20") //$NON-NLS-1$
				+ Messages.getString("AR_premier.21") //$NON-NLS-1$
				+ String.valueOf(location.getLatitude())
				+ Messages.getString("AR_premier.22") //$NON-NLS-1$
				+ String.valueOf(location.getLongitude())
				+ Messages.getString("AR_premier.23") //$NON-NLS-1$
				+ String.valueOf(range) + Messages.getString("AR_premier.24"); //$NON-NLS-1$
		String url2 = Messages.getString("AR_premier.20") //$NON-NLS-1$
				+ Messages.getString("AR_premier.21") //$NON-NLS-1$
				+ String.valueOf(location.getLatitude())
				+ Messages.getString("AR_premier.22") //$NON-NLS-1$
				+ String.valueOf(location.getLongitude())
				+ Messages.getString("AR_premier.23") //$NON-NLS-1$
				+ String.valueOf(range) + Messages.getString("AR_premier.24bis"); //$NON-NLS-1$
		Random r= new Random();
		if(r.nextBoolean()){
			url=url1;
		}else{
			url=url2;
		}
		
		return url;
	}

	private SeekBar radius_bar;

	private TextView radius_text;

	/** Lance l'application écrire un émail
	 * 
	 */
	private void contacter(){
		final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
		
		emailIntent.setType("plain/text");
		emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"emmanuel.rosetti@gmail.com"});
		emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Remarques table d'orientation");
		emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,"Vos remarques: ");
		
		startActivity(Intent.createChooser(emailIntent, "Envoyer un email..."));
	}
	/**Affiche des informations sur l'application
	 * 
	 */
	public void informations(){
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		
		final SpannableString s= new SpannableString("Application de réalité augmentée développée par Emmanuel Rosetti dans le cadre d'un Projet Informatique de la formation ingénieur 3ème année ENSG.\nCe projet a été commandité par M.Hervé Quinquenel.\nSont utilisés:\n - l' API Google Maps pour la visualisation cartographique\n - l'API Wikitude pour la réalité augmenté\n - le webService GeoNames pour l'altitude des points et la base de données de POIs wikipedia\nPlus d'informations en ligne sur http://code.google.com/p/table-d-orientation\nContact: emmanuel.rosetti@gmail.com\n\u00A9 2012");
		Linkify.addLinks(s, Linkify.ALL);
		builder.setTitle("A propos")
				.setMessage(s)
				.setIcon(R.drawable.ic_launcher)
				.setCancelable(false)
				.setPositiveButton("Ok",
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});
		AlertDialog alert = builder.create();
		alert.show();
		((TextView)alert.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

	}

	/**
	 * Determines whether one Location reading is better than the current
	 * Location fix
	 * 
	 * @param location
	 *            The new Location that you want to evaluate
	 * @param currentBestLocation
	 *            The current Location fix, to which you want to compare the new
	 *            one
	 */
	protected boolean isBetterLocation(Location location,
			Location currentBestLocation) {
		if (currentBestLocation == null) {
			// A new location is always better than no location
			return true;
		}
		Log.i(Tag, Messages.getString("AR_premier.66") + location.getAccuracy() //$NON-NLS-1$
				+ Messages.getString("AR_premier.67")); //$NON-NLS-1$
		// Check whether the new location fix is newer or older
		long timeDelta = location.getTime() - currentBestLocation.getTime();
		boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
		boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
		boolean isNewer = timeDelta > 0;

		// If it's been more than two minutes since the current location, use
		// the new location
		// because the user has likely moved
		if (isSignificantlyNewer) {
			return true;
			// If the new location is more than two minutes older, it must be
			// worse
		} else if (isSignificantlyOlder) {
			return false;
		}

		// Check whether the new location fix is more or less accurate
		int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
				.getAccuracy());
		boolean isLessAccurate = accuracyDelta > 0;
		boolean isMoreAccurate = accuracyDelta < 0;
		boolean isSignificantlyLessAccurate = accuracyDelta > 200;

		// Check if the old and new location are from the same provider
		boolean isFromSameProvider = isSameProvider(location.getProvider(),
				currentBestLocation.getProvider());

		// Determine location quality using a combination of timeliness and
		// accuracy
		if (isMoreAccurate) {
			return true;
		} else if (isNewer && !isLessAccurate) {
			return true;
		} else if (isNewer && !isSignificantlyLessAccurate
				&& isFromSameProvider) {
			return true;
		}
		return false;
	}
	/** Checks whether two providers are the same 
	 * @param provider1
	 * @param provider2
	 * @return
	 */
	private boolean isSameProvider(String provider1, String provider2) {
		if (provider1 == null) {
			return provider2 == null;
		}
		return provider1.equals(provider2);
	}
	
	/**Crée une liste de POIs définis en "dur"
	 * @param
	 * @return liste de POIs 
	 */
	@SuppressWarnings("unused")
	private ArrayList<WikitudePOI> ListPois() {

		WikitudePOI poi1 = new WikitudePOI(
				48.841447,
				2.58728,
				getElevationfromGeonames(2.58728, 48.841447),
				Messages.getString("AR_premier.47"), //$NON-NLS-1$
				Messages.getString("AR_premier.48"), Messages.getString("AR_premier.49"), //$NON-NLS-1$ //$NON-NLS-2$
				null, null, null);
		Log.i(Tag,
				Messages.getString("AR_premier.50") + Double.toString(poi1.getAltitude())); //$NON-NLS-1$
		WikitudePOI poi2 = new WikitudePOI(48.840416, 2.583876,
				getElevationfromGeonames(2.583876, 48.840416),
				Messages.getString("AR_premier.51"), //$NON-NLS-1$
				Messages.getString("AR_premier.52")); //$NON-NLS-1$
		Log.i(Tag,
				Messages.getString("AR_premier.53") + Double.toString(poi2.getAltitude())); //$NON-NLS-1$
		WikitudePOI poi3 = new WikitudePOI(48.84132, 2.591785,
				getElevationfromGeonames(2.591785, 48.84132),
				Messages.getString("AR_premier.54"), //$NON-NLS-1$
				Messages.getString("AR_premier.55")); //$NON-NLS-1$
		Log.i(Tag,
				Messages.getString("AR_premier.56") + Double.toString(poi3.getAltitude())); //$NON-NLS-1$
		WikitudePOI poi4 = new WikitudePOI(
				48.842732,
				2.578246,
				getElevationfromGeonames(2.578246, 48.842732),
				Messages.getString("AR_premier.57"), Messages.getString("AR_premier.58")); //$NON-NLS-1$ //$NON-NLS-2$
		Log.i(Tag,
				Messages.getString("AR_premier.59") + Double.toString(poi4.getAltitude())); //$NON-NLS-1$
		WikitudePOI poi5 = new WikitudePOI(
				48.82,
				2.56,
				getElevationfromGeonames(2.56, 48.82),
				Messages.getString("AR_premier.60"), Messages.getString("AR_premier.61")); //$NON-NLS-1$ //$NON-NLS-2$
		Log.i(Tag,
				Messages.getString("AR_premier.62") + Double.toString(poi5.getAltitude())); //$NON-NLS-1$
		WikitudePOI poi6 = new WikitudePOI(48.853597, 2.604048,
				getElevationfromGeonames(2.56, 48.82),
				Messages.getString("AR_premier.63"), //$NON-NLS-1$
				Messages.getString("AR_premier.64")); //$NON-NLS-1$
		Log.i(Tag,
				Messages.getString("AR_premier.65") + Double.toString(poi5.getAltitude())); //$NON-NLS-1$
		ArrayList<WikitudePOI> pois = new ArrayList<WikitudePOI>();
		pois.clear();
		pois.add(poi1);
		pois.add(poi2);
		pois.add(poi3);
		pois.add(poi4);
		pois.add(poi5);
		pois.add(poi6);

		Log.i(Tag, pois.toString());

		return (pois);
	}
	
	/**Appelée à la pression sur le bouton "back" pour fermer l'application*/
	/* (non-Javadoc)
	 * @see android.app.Activity#onBackPressed()
	 */
	@Override
	public void onBackPressed() {
		quitter();

	}
	
	/** Called when the activity is first created. */
	/* (non-Javadoc)
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.main);
        setProgressBarIndeterminateVisibility(mToggleIndeterminate);

		if (range_tot > 1) {

		} else {
			range_tot = 1;
		}
		final Handler myHandler=new Handler();
		
		final Runnable loading= new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				while(chargé!=true){
					
				}
				
				mToggleIndeterminate = !mToggleIndeterminate;
                setProgressBarIndeterminateVisibility(mToggleIndeterminate);
			}
		};
		
		
		/**On enregistre des préférences afin de pouvoir recharger des points rapidements.
		 * 
		 */
		SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
		double latitude_pref = settings.getFloat("latitude", (float) 48.841447);
		double longitude_pref = settings.getFloat("longitude", (float) 2.58728);
		ici = new Location("dummyprovider");
		ici.setLatitude(latitude_pref);
		ici.setLongitude(longitude_pref);

		ajoutPOIs = (Button) findViewById(R.id.ajout);
		voirPOIs = (Button) findViewById(R.id.voir);
		arwikitude = (Button) findViewById(R.id.orientation);
		artout = (Button) findViewById(R.id.RA);
		mappoi = (Button) findViewById(R.id.carte);
		radius_bar = (SeekBar)findViewById(R.id.seekBar_radius);
		radius_text = (TextView)findViewById(R.id.radius_text);

		final Intent intent_ajoutPOIs = new Intent(this, AjoutPOIs.class);
		final Intent intent_voirPOIs = new Intent(this, VoirPOIs.class);
		final Intent intent_map = new Intent(this, mapPOI.class);

		voirPOIs.setEnabled(false);
		ajoutPOIs.setEnabled(false);
		voirPOIs.setVisibility(8);
		ajoutPOIs.setVisibility(8);
		
		radius_bar.setMax(9);
		radius_bar.incrementProgressBy(1);
		radius_bar.setProgress(range_tot-1);
		radius_text.setText("Rayon de "+range_tot+" km");
		
		/**Réactions au changement de la barre de progression de paramètres
		 * 
		 */
		SeekBar.OnSeekBarChangeListener SBlistener = new SeekBar.OnSeekBarChangeListener() {
			
			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
				// TODO Auto-generated method stub
				if(fromUser){
				range_tot=progress+1;
				list_pois_base_wiki=null;
				visibles_temp=null;
				radius_text.setText("Rayon de "+range_tot+" km");
				chargé=false;
				mToggleIndeterminate =true;
                setProgressBarIndeterminateVisibility(mToggleIndeterminate);
                               
                if (reload == null || !reload.isAlive()){
                reload=new Thread(new Runnable(){
                
	                @Override
					public void run() {
						
						
						list_pois_base_wiki = getPOISWiki2(ici, range_tot,
								getApplicationContext());
					
						if (reload_visible.isAlive()) {
	
						} else {
							reload_visible.start();
	
						}
						myHandler.post(loading);
						if (list_pois_base_wiki.size()==0){
							myHandler.post(new Runnable() {
								public void run() {
									Toast.makeText(getApplicationContext(),"La limite de requête par heure a été atteinte, veuillez réessayer ultérieurement.",Toast.LENGTH_LONG).show();
								}
							});
						}
					} 
					
					
	                },"reload");
                reload.start();
                }
                
                
                if (reload_visible == null||!reload_visible.isAlive()) {
        			reload_visible = new Thread(new Runnable() {

        				/* (non-Javadoc)
        				 * @see java.lang.Runnable#run()
        				 */
        				@Override
        				public void run() {
        					
        					visibles_temp = POIsVisible(ici, list_pois_base_wiki,
        							range_tot * 1000);

        				}
        			}, "reload visible");
        		}
                
				}
			}
			
			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
				
			}
		};
		radius_bar.setOnSeekBarChangeListener(SBlistener);
		
			

		/**Lancement du thread récupérant tout les POIs via Wiki
		 * 
		 */
		if (test == null || !test.isAlive()) {
			test = new Thread(new Runnable() {

				/* (non-Javadoc)
				 * @see java.lang.Runnable#run()
				 */
				@Override
				public void run() {
					
					
					list_pois_base_wiki = getPOISWiki2(ici, range_tot,
							getApplicationContext());
				
					if (thread_visible.isAlive()) {

					} else {
						thread_visible.start();

					}
					myHandler.post(loading);
					if (list_pois_base_wiki.size()==0){
						myHandler.post(new Runnable() {
							public void run() {
								Toast.makeText(getApplicationContext(),"La limite de requête par heure a été atteinte, veuillez réessayer ultérieurement.",Toast.LENGTH_LONG).show();
							}
						});
					}
				} 
				
				
			}, Messages.getString("AR_premier.12")); //$NON-NLS-1$
		}
		
		/**Lancement du Thread calculant les POIs visibles
		 * 
		 */
		if (thread_visible == null) {
			thread_visible = new Thread(new Runnable() {

				/* (non-Javadoc)
				 * @see java.lang.Runnable#run()
				 */
				@Override
				public void run() {
					
					visibles_temp = POIsVisible(ici, list_pois_base_wiki,
							range_tot * 1000);

				}
			}, "calcul POISvisibles seul");
		}

		/**Réaction au clic sur Table d'orientation
		 * 
		 */
		OnClickListener CL_wikitude = new OnClickListener() {

			@Override
			public void onClick(View v) {
				wiki_visible=null;
				/*							
				if (list_pois_base_wiki != null) {
					
					final WikitudeARIntent intent = new WikitudeARIntent(
							getApplication(),
							Messages.getString("AR_premier.45"),
							Messages.getString("AR_premier.46"));
					intent.addPOIs(list_pois_base_wiki);
					intent.setPrintMarkerSubText(true);

					startActivity(intent);
					
					Thread a= new Thread(new Runnable() {
						
						@Override
						public void run() {
							
							//
							int taille=intent.getPOIsSize();
							for(int i=0;i<intent.getPOIsSize();i++){
								if(AR_premier.isPOIVisible(ici, intent.getPOI(i),range_tot)==false){
									intent.removePOI(i);
									i=i-1;
								}else{
									continue;
								}
								
							}
							if(taille!=intent.getPOIsSize()){
							//	startActivity(intent);
							}
							
														
						}
					}, "calcul visibilité");
					a.start();

				
				} else {
					Toast.makeText(getApplicationContext(),
							"Chargement des POIs depuis wikipedia en cours",
							Toast.LENGTH_LONG).show();
				}
*/
				
				poisvisibles2 = visibles_temp;
				if (poisvisibles2 != null) {

					try {

						final WikitudeARIntent intent = prepareIntent();
						// Optionally add a title
						intent.addTitleText(Messages.getString("AR_premier.4")); //$NON-NLS-1$
						
						startActivity(intent);
						wiki_visible = new Thread(new Runnable() {

							/* (non-Javadoc)
							 * @see java.lang.Runnable#run()
							 */
							@Override
							public void run() {
								//list_pois_base_wiki=null;//test
								list_pois_base_wiki = getPOISWiki2(ici,
										range_tot, getApplicationContext());
								
								ici = locationManager.getLastKnownLocation(GpsProvider);
								Collection<WikitudePOI> poisvisibles3 = poisvisibles2; // POIsVisible(ici,
																						// list_pois_base_wiki,
																						// range_tot*1000);
								if (poisvisibles3.size() == intent
										.getPOIsSize())// On ne cherche que en
								// fonction de la
								// taille!!
								{
									Log.i(Tag,
											Messages.getString("AR_premier.5")); //$NON-NLS-1$
									this.run();
								} else {
									if (poisvisibles3 != null) {
										Log.i(Tag, Messages
												.getString("AR_premier.6")); //$NON-NLS-1$
										for (int i = 0; i < intent
												.getPOIsSize(); i++) {
											intent.removePOI(i);
										}
										intent.addPOIs(poisvisibles3);
										
									}
									
								}
								
								poisvisibles3=null;

							}
						}, Messages.getString("AR_premier.7")); //$NON-NLS-1$
						wiki_visible.start();
						

					} catch (ActivityNotFoundException e) {
						/*Toast.makeText(getApplicationContext(),
								Messages.getString("AR_premier.8"), //$NON-NLS-1$
								Toast.LENGTH_SHORT).show();*/
						
						AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
						
						final SpannableString s= new SpannableString("L'application Wikitude n'est pas installée sur votre mobile.\nLa réalité augmentée ne pourra pas fonctionner si cette application n'est pas installée.\nSi vous désirez l'installer, rendez vous sur https://market.android.com/details?id=com.wikitude&feature=search_result");
						Linkify.addLinks(s, Linkify.ALL);
						builder.setTitle("Wikitude n'est pas installée")
								.setMessage(s)
								.setCancelable(false)
								.setPositiveButton("Ok",
										new DialogInterface.OnClickListener() {
											@Override
											public void onClick(DialogInterface dialog, int id) {
												dialog.cancel();
											}
										});
						AlertDialog alert = builder.create();
						alert.show();
						((TextView)alert.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

						
					}
				} else {
					Toast.makeText(getApplicationContext(),
							Messages.getString("AR_premier.9"), //$NON-NLS-1$
							Toast.LENGTH_LONG).show();
				}
				
			}
		};
		
		/**Réaction au clic sur Ajout Pois
		 * non implémenté
		 */
		OnClickListener CL_ajoutPOIs = new OnClickListener() {

			@Override
			public void onClick(View v) {
				startActivity(intent_ajoutPOIs);
			}
		};
		
		/**Réaction au clic sur Voir Pois
		 * non implémenté
		 */
		OnClickListener CL_voirPOIs = new OnClickListener() {

			@Override
			public void onClick(View v) {

				startActivity(intent_voirPOIs);
			}
		};
		
		/**Réaction au clic sur Réalité augmentée avec tous les points.
		 * 
		 */
		OnClickListener CL_ARtout = new OnClickListener() {

			@Override
			public void onClick(View v) {

				if (list_pois_base_wiki != null) {
					WikitudeARIntent intent = new WikitudeARIntent(
							getApplication(),
							Messages.getString("AR_premier.45"),
							Messages.getString("AR_premier.46"));
					intent.addPOIs(list_pois_base_wiki);
					intent.setPrintMarkerSubText(true);

					startActivity(intent);
				} else {
					Toast.makeText(getApplicationContext(),
							"Chargement des POIs depuis wikipedia en cours",
							Toast.LENGTH_LONG).show();
				}

			}
		};
		
		/**
		 * Réaction au clic sur Carte avec tous les POIs
		 */
		OnClickListener CL_map = new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (list_pois_base_wiki != null) {
					listtoutpois = list_pois_base_wiki;
					
					startActivity(intent_map);
				} else {
					Toast.makeText(getApplicationContext(),
							"Chargement des POIs depuis wikipedia en cours",
							Toast.LENGTH_LONG).show();
				}

			}
		};

		ajoutPOIs.setOnClickListener(CL_ajoutPOIs);
		voirPOIs.setOnClickListener(CL_voirPOIs);
		arwikitude.setOnClickListener(CL_wikitude);
		artout.setOnClickListener(CL_ARtout);
		mappoi.setOnClickListener(CL_map);
	}
	
	/**
	 * Création du Menu
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.menubar, menu);
	    return true;
	}
	
	/* (non-Javadoc)
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	public void onDestroy() {

		super.onDestroy();
	}

	/**
	 * Actions appelées lors du clic sur les items du menu
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	        case R.id.about:
	            informations();
	            return true;
	        case R.id.contact:
	            contacter();
	            return true;
	        case R.id.abort:
	            quitter();
	            return true;
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onPause()
	 */
	@Override
	public void onPause() {
		
		
		super.onPause();

	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onResume()
	 */
	@Override
	public void onResume() {

		super.onResume();

		if (range_tot > 1) {
			this.radius_bar.setProgress(range_tot-1);

		} else {
			range_tot = 1;
			this.radius_bar.setProgress(0);
		}

	}
	/**Au démarrage de l'activité
	 * 
	 */
	/* (non-Javadoc)
	 * @see android.app.Activity#onStart()
	 */
	@Override
	public void onStart() {
		super.onStart();

		locationManager = (LocationManager) this
				.getSystemService(Context.LOCATION_SERVICE);
		GpsProvider = LocationManager.GPS_PROVIDER;
		networkProvider = LocationManager.NETWORK_PROVIDER;

		listenerGPS = new LocationListener() {

			/* (non-Javadoc)
			 * @see android.location.LocationListener#onLocationChanged(android.location.Location)
			 */
			@Override
			public void onLocationChanged(Location location) {
				
				boolean b = isBetterLocation(location, ici);
				if (b) {
					ici = location;
					Log.i(Tag,
							Messages.getString("AR_premier.10") + ici.getLatitude() + Messages.getString("AR_premier.11") //$NON-NLS-1$ //$NON-NLS-2$
									+ ici.getLongitude());
				}

				if (!test.isAlive()&&!thread_visible.isAlive()) 
				{
					try {
						test.setPriority(Thread.NORM_PRIORITY);
						test.start();
					} catch (IllegalThreadStateException e) {
						e.printStackTrace();
					}
				}
			}

			@Override
			public void onProviderDisabled(String provider) {

			}

			@Override
			public void onProviderEnabled(String provider) {

			}

			@Override
			public void onStatusChanged(String provider, int status,
					Bundle extras) {

			}

		};

		boolean isGPS = locationManager
				.isProviderEnabled(LocationManager.GPS_PROVIDER);
		if (isGPS == false) {
			Toast.makeText(getApplicationContext(),
					Messages.getString("AR_premier.13"), Toast.LENGTH_SHORT) //$NON-NLS-1$
					.show();
			startActivity(new Intent(
					android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
		} else {
			locationManager.requestLocationUpdates(GpsProvider, 30000, 50,
					listenerGPS);
			ici = locationManager.getLastKnownLocation(GpsProvider);
			locationManager.getLastKnownLocation(networkProvider);

		}

	}
	/**Au stop de l'activité
	 * 
	 */
	/* (non-Javadoc)
	 * @see android.app.Activity#onStop()
	 */
	@Override
	public void onStop() {
		super.onStop();

		// We need an Editor object to make preference changes.
		// All objects are from android.context.Context
		SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
		SharedPreferences.Editor editor = settings.edit();
		if(ici!=null){
			editor.putFloat("latitude", (float) ici.getLatitude());
			editor.putFloat("longitude", (float) ici.getLongitude());
		}
		
		Log.i(Tag, Float.toString(settings.getFloat("latitude", 0)));
		// Commit the edits!
		editor.commit();

	}

	/** Calcul des POIs visibles d'un ArrayList de POI
	 * @param location Position actuelle
	 * @param poisbase Liste de WikitudePOI 
	 * @param range Rayon de visibilité
	 * @return poisvisibles Collection de WikitudePOI
	 */
	static Collection<WikitudePOI> POIsVisible(Location location,
			ArrayList<WikitudePOI> poisbase, int range) {

		Collection<WikitudePOI> poisvisible = null;
		ArrayList<WikitudePOI> poisbase2 = poisbase;
		if (location != null) {
			double lat = location.getLatitude();
			double longi = location.getLongitude();
			double alti = getElevationfromGeonames(longi, lat);
			Log.i(Tag, Messages.getString("AR_premier.30") + alti); //$NON-NLS-1$
			int k = 0;
			for (int i = 0; i < poisbase2.size(); i++) {
				k = k + 1;
				Log.i(Tag,
						Messages.getString("AR_premier.31") + (k) + Messages.getString("AR_premier.32") + poisbase2.size()); //$NON-NLS-1$ //$NON-NLS-2$
				WikitudePOI poi = poisbase2.get(i);
				Location poi_loc = new Location(location);
				poi_loc.reset();
				poi_loc.setLatitude(poi.getLatitude());
				poi_loc.setLongitude(poi.getLongitude());
				poi_loc.setAltitude(poi.getAltitude());
				double R = 6400000;
				double dist_trig = R
						* Math.acos(Math.sin(lat * Math.PI / 180)
								* Math.sin(poi_loc.getLatitude() * Math.PI
										/ 180)
								+ Math.cos(lat * Math.PI / 180)
								* Math.cos(poi_loc.getLatitude() * Math.PI
										/ 180)
								* Math.cos((poi_loc.getLongitude() - longi)
										* Math.PI / 180));
				Log.i(Tag,
						Messages.getString("AR_premier.33") + (k) + Messages.getString("AR_premier.34") + dist_trig); //$NON-NLS-1$ //$NON-NLS-2$
				if (dist_trig <= range) {
					for (int j = 30; j < dist_trig; j = j + 30) {
						Location loca_int = new Location(location);
						loca_int.reset();
						loca_int.setLatitude((poi_loc.getLatitude() - lat)
								* (j / dist_trig) + lat);
						loca_int.setLongitude((poi_loc.getLongitude() - longi)
								* (j / dist_trig) + longi);
						loca_int.setAltitude(getElevationfromGeonames(
								loca_int.getLongitude(), loca_int.getLatitude()));
						double alti_attendue = (poi_loc.getAltitude() - alti)
								* (j / dist_trig) + alti;
						if (loca_int.getAltitude() > alti_attendue + 5) {
							Log.i(Tag,
									Messages.getString("AR_premier.35") + (k) //$NON-NLS-1$
											+ Messages
													.getString("AR_premier.36")); //$NON-NLS-1$
							Log.i(Tag,
									Messages.getString("AR_premier.37") + loca_int.getLatitude() //$NON-NLS-1$
											+ Messages
													.getString("AR_premier.38") + loca_int.getLongitude() + Messages.getString("AR_premier.39") //$NON-NLS-1$ //$NON-NLS-2$
											+ loca_int.getAltitude());
							Log.i(Tag,
									Messages.getString("AR_premier.40") + alti_attendue); //$NON-NLS-1$
							poisbase.remove(i);

							Log.i(Tag,
									Messages.getString("AR_premier.41") + poisbase2.size()); //$NON-NLS-1$
							i = i - 1;
							break;
						} else {

						}
					}
				} else if (dist_trig > range) {
					Log.i(Tag, Messages.getString("AR_premier.42") + (k) //$NON-NLS-1$
							+ Messages.getString("AR_premier.43")); //$NON-NLS-1$
					poisbase2.remove(i);

					Log.i(Tag,
							Messages.getString("AR_premier.44") + poisbase2.size()); //$NON-NLS-1$
					i = i - 1;
				}

				poi = null;
			}
		}

		poisvisible = poisbase2;
		poisbase2=null;
		
		return poisvisible;
	}

	/**Fonction statique évaluant pour un POI si il est visible ou non
	 * 
	 * @param location Position actuelle
	 * @param poi POI à évaluer
	 * @param range Rayon de visibilité
	 * @return visible Booléen, true= visible, false=invisible
	 */
	static boolean isPOIVisible(Location location,WikitudePOI poi, int range) {
		boolean visible=true;
		
		if (location != null) {
			double lat = location.getLatitude();
			double longi = location.getLongitude();
			double alti = getElevationfromGeonames(longi, lat);
			Log.i(Tag, Messages.getString("AR_premier.30") + alti); //$NON-NLS-1$
			Location poi_loc = new Location(location);
			poi_loc.reset();
			poi_loc.setLatitude(poi.getLatitude());
			poi_loc.setLongitude(poi.getLongitude());
			poi_loc.setAltitude(poi.getAltitude());
			double R = 6400000;
			double dist_trig = R
						* Math.acos(Math.sin(lat * Math.PI / 180)
								* Math.sin(poi_loc.getLatitude() * Math.PI
										/ 180)
								+ Math.cos(lat * Math.PI / 180)
								* Math.cos(poi_loc.getLatitude() * Math.PI
										/ 180)
								* Math.cos((poi_loc.getLongitude() - longi)
										* Math.PI / 180));
			if (dist_trig <= range) {
					for (int j = 30; j < dist_trig; j = j + 30) {
						Location loca_int = new Location(location);
						loca_int.reset();
						loca_int.setLatitude((poi_loc.getLatitude() - lat)
								* (j / dist_trig) + lat);
						loca_int.setLongitude((poi_loc.getLongitude() - longi)
								* (j / dist_trig) + longi);
						loca_int.setAltitude(getElevationfromGeonames(
								loca_int.getLongitude(), loca_int.getLatitude()));
						double alti_attendue = (poi_loc.getAltitude() - alti)
								* (j / dist_trig) + alti;
						if (loca_int.getAltitude() > alti_attendue + 5) {
							
							Log.i(Tag,
									Messages.getString("AR_premier.37") + loca_int.getLatitude() //$NON-NLS-1$
											+ Messages
													.getString("AR_premier.38") + loca_int.getLongitude() + Messages.getString("AR_premier.39") //$NON-NLS-1$ //$NON-NLS-2$
											+ loca_int.getAltitude());
							Log.i(Tag,
									Messages.getString("AR_premier.40") + alti_attendue); //$NON-NLS-1$
							visible=false;
							break;
						} else {
							visible=true;
						}
					}
				} else if (dist_trig > range) {
					
					visible=false;
					
				}

				
			
		}

		

		return visible;
	}
	
	/**
	 * prepares a Wikitude AR Intent (e.g. adds the POIs to the view)
	 * 
	 * @return the prepared intent
	 */
	/**
	 * @return
	 */
	private WikitudeARIntent prepareIntent() {
		// create the intent
		WikitudeARIntent intent = new WikitudeARIntent(
				this.getApplication(),
				Messages.getString("AR_premier.45"), Messages.getString("AR_premier.46")); //$NON-NLS-1$ //$NON-NLS-2$

		// add the POIs
		// Collection<WikitudePOI> poisvisibles = POIsVisible(ici, ListPois(),
		// 1000);
		intent.addPOIs(poisvisibles2);
		return intent;
	}

	/**Fonction pour quitter l'activité
	 * 
	 */
	public void quitter(){
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(Messages.getString("AR_premier.1")) //$NON-NLS-1$
				.setCancelable(false)
				.setPositiveButton(Messages.getString("AR_premier.2"), //$NON-NLS-1$
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int id) {
								locationManager.removeUpdates(listenerGPS);

								AR_premier.this.finish();

								AR_premier.this.onDestroy();
							}
						})
				.setNegativeButton(Messages.getString("AR_premier.3"), //$NON-NLS-1$
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});
		AlertDialog alert = builder.create();
		alert.show();
		
	}

}
